package com.zyf.project.capchain.utils.common;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.zyf.project.capchain.utils.cryptology.EncryptUtils;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.impl.DefaultClaims;
import lombok.Data;
import io.jsonwebtoken.Jwts;
import org.jetbrains.annotations.NotNull;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.security.PrivateKey;
import java.util.Date;

/**
 * @author Zhou Yifan
 */
@Data
@Component
@PropertySource("classpath:jwt.properties")
@ConfigurationProperties(prefix = "jwt")
public class JwtUtils {

    /**
     * 密钥
     */
    private String secret;

    /**
     * 过期时间
     */
    private long expire;

    /**
     * 请求头名称
     */
    private String header;

    /**
     * 生成 JWT token
     *
     * @param session session
     * @return token
     */
    public String getToken(String session) {
        Date nowDate = new Date();
        Date expireDate = new Date(nowDate.getTime() + expire * 1000);

        return Jwts.builder()
                .setHeaderParam("typ", "JWT")
                .setSubject(session)
                .setIssuedAt(nowDate)
                .setExpiration(expireDate)
                .signWith(SignatureAlgorithm.HS256, secret)
                .compact();
    }

    /**
     * 从 request 中获取 openid
     *
     * @param request http 请求
     * @return openid
     */
    public String getOpenidFromRequest(@NotNull HttpServletRequest request) {
        return getOpenidFromToken(request.getHeader(header));
    }

    /**
     * 从 token 中获取 openid
     *
     * @param token token
     * @return openid
     */
    public String getOpenidFromToken(String token) {
        String openid;
        String session;
        try {
            // 解析token获取session
            Claims claims = getClaimByToken(token);
            session = claims.getSubject();

            // 解密session
            PrivateKey privateKey = EncryptUtils.getPrivateKey();
            String jsonString = EncryptUtils.decryptRSA(session, privateKey);

            // 解密的结果转为json
            JSONObject jsonObject = JSON.parseObject(jsonString);

            openid = jsonObject.getString("openid");
            return openid;

        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 从token中获取荷载
     *
     * @param token token
     * @return cliam
     */
    public Claims getClaimByToken(String token) {
        try {
            return Jwts.parser()
                    .setSigningKey(secret)
                    .parseClaimsJws(token)
                    .getBody();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new DefaultClaims();
    }

    /**
     * 校验token
     *
     * @param token token
     */
    public void verifyToken(String token) {
        Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();
    }

}
